package com.gitee.wsl.doc.prosemirror.ui.command

import com.gitee.wsl.doc.prosemirror.model.content.ext.findCutBefore
import com.gitee.wsl.doc.prosemirror.model.content.ext.liftTarget
import com.gitee.wsl.doc.prosemirror.model.fragment.Slice
import com.gitee.wsl.doc.prosemirror.model.node.ext.TextblockSide
import com.gitee.wsl.doc.prosemirror.model.node.ext.textblockAt
import com.gitee.wsl.doc.prosemirror.state.Command
import com.gitee.wsl.doc.prosemirror.state.CommandDispatch
import com.gitee.wsl.doc.prosemirror.state.EditorState
import com.gitee.wsl.doc.prosemirror.state.Transaction
import com.gitee.wsl.doc.prosemirror.state.ext.deleteBarrier
import com.gitee.wsl.doc.prosemirror.state.selection.NodeSelection
import com.gitee.wsl.doc.prosemirror.state.selection.Selection
import com.gitee.wsl.doc.prosemirror.transform.ext.delete
import com.gitee.wsl.doc.prosemirror.transform.ext.lift
import com.gitee.wsl.doc.prosemirror.transform.ext.replaceStep
import com.gitee.wsl.doc.prosemirror.transform.ext.step
import com.gitee.wsl.doc.prosemirror.transform.step.ReplaceStep
import com.gitee.wsl.doc.prosemirror.ui.EditorView
import com.gitee.wsl.doc.prosemirror.ui.ext.atBlockStart

object JoinBackward:UiCommand{
    override fun exec(
        view: EditorView?,
        state: EditorState,
        dispatch: CommandDispatch?,
    ): Boolean {
        // 检测光标是否位于块起始位置
        val cursor = atBlockStart(state, view) ?: return false

        // 查找前面的切割点
        val cut = cursor.findCutBefore()

        // 情况1：前面没有节点，尝试提升当前块
        if (cut == null) {
            val range = cursor.blockRange()
            val target = range?.liftTarget() ?: return false

            dispatch?.invoke(state.tr.lift(range, target).scrollIntoView())
            return true
        }

        val before = cut.nodeBefore ?: return false

        // 情况2：应用合并算法删除屏障
        if (state.deleteBarrier( cut, dispatch, -1)) {
            return true
        }

        // 情况3：下方节点无内容且上方节点可选，删除下方节点并选择上方节点
        if (cursor.parent.content.size == 0 && (before.textblockAt(TextblockSide.end) || NodeSelection.isSelectable(
                before
            ))
        ) {
            var depth = cursor.depth
            while (true) {
                val delStep = state.doc.replaceStep(
                    cursor.before(depth),
                    cursor.after(depth),
                    Slice.empty
                )

                if (delStep is ReplaceStep && delStep.slice.size < delStep.to - delStep.from) {
                    dispatch?.let {
                        val tr = state.tr.step(delStep)
                        val newSelection = if (before.textblockAt( TextblockSide.end)) {
                            Selection.findFrom(
                                tr.doc.resolve(
                                    tr.mapping.map(
                                        cut.pos, -1
                                    )
                                ), -1
                            )
                        } else {
                            NodeSelection.create(tr.doc, cut.pos - before.nodeSize)
                        }

                        it.invoke(tr.scrollIntoView())
                        return true
                    }

                    if (depth == 1 || cursor.node(depth - 1).childCount > 1) {
                        break
                    }
                    depth--
                }
            }
        }
         // 情况4：前面是原子节点且在同一层级，删除它
         if (before.isAtom && cut.depth == cursor.depth - 1) {
             dispatch?.invoke(
                 state.tr.delete(cut.pos - before.nodeSize, cut.pos).scrollIntoView()
             )
             return true
         }

         return false
    }
}

val Command.Companion.joinBackward :UiCommand
    get() = JoinBackward

